from flask import current_app, request
from flask_restx import abort, reqparse
from sqlalchemy import and_

from app.models import classesModel, roleModel, userModel
from tools import db
from utils.utils import base_detail

from .base_view import OrganizerBase


class Classes(OrganizerBase):
    def get_class_info(self, id=None, name=None):
        class_info = None
        if id:
            class_info = classesModel.Classes.query.filter_by(id=id).first()
        elif name:
            class_info = classesModel.Classes.query.filter_by(name=name).first()
        return class_info


class ClassManage(Classes):
    def get(self, id=None):
        class_info = self.get_class_info(id=id)
        if not class_info:
            abort(400, message="班级不存在")
        return {"code": 200, "data": class_info.to_dict()}

    def post(self):
        parser = reqparse.RequestParser(bundle_errors=True)
        parser.add_argument("class_name", help="班级名称不能为空", required=True)
        parser.add_argument("grade", help="年级不能为空", required=True)
        # parser.add_argument('major', help='专业不能为空', required=True)
        args = parser.parse_args()
        if not all([args["class_name"], args["grade"]]):
            abort(400, message="参数错误")

        # 判断班级名是否存在
        class_info = self.get_class_info(name=args["class_name"])
        if class_info:
            abort(400, message="班级名已存在，请更换！")

        with db.auto_commit():
            class_obj = classesModel.Classes(
                name=args.get("class_name"), grade=args.get("grade")
            )
            classesModel.db.session.add(class_obj)
            classesModel.db.session.commit()
            current_app.logger.info(
                self.user.username + "---action--add--class:" + args["class_name"]
            )
            return {"code": 200, "data": class_obj.to_dict()}

    def put(self, id=None):
        if not id:
            abort(400, message="参数错误")

        parser = reqparse.RequestParser(bundle_errors=True)
        parser.add_argument("class_name", help="班级名称不能为空", required=True)
        parser.add_argument("grade", help="年级不能为空", required=True)
        # parser.add_argument('major', help='专业不能为空', required=True)
        args = parser.parse_args()
        if not all([args["class_name"], args["grade"]]):
            abort(400, message="参数错误")

        class_info = self.get_class_info(id=id)
        if not class_info:
            abort(400, message="该班级不存在")

        # 判断班级名
        class_info_by_name = self.get_class_info(name=args["class_name"])
        if class_info_by_name and class_info_by_name.id != id:
            abort(400, message="班级名已存在，请更换！")

        with db.auto_commit():
            class_info.name = args["class_name"]
            class_info.grade = args.get("grade")
            current_app.logger.info(
                self.user.username + "---action--put--class:" + args["class_name"]
            )
            return {"code": 200, "data": class_info.to_dict()}

    def delete(self, id=None):
        with db.auto_commit():
            class_info = self.get_class_info(id=id)
            if not class_info:
                abort(400, message="class not exist")
            db.session.delete(class_info)
        return {"code": 200, "data": "删除成功"}


class ClassList(Classes):
    def get(self):
        params = request.args
        page = params.get("page", 1)
        page_size = params.get("pageSize", 10)
        keyword = params.get("keyword")
        try:
            page = int(page)
            page_size = int(page_size)
        except Exception as e:  # noqa
            page = 1
            page_size = 10

        if page_size >= 50:
            abort(400, message="每页数量不能超过50")

        try:
            filters = []
            if keyword:
                # 添加关键词的检索选项
                filters.append(classesModel.Classes.name.contains(keyword))

            paginate = (
                classesModel.Classes.query.filter(*filters)
                .order_by(classesModel.Classes.id.desc())
                .paginate(page, page_size, error_out=False)
            )

            info = dict()  # noqa
            info["current_page"] = page
            info["data"] = []
            if len(paginate.items) > 0:
                for content in paginate.items:
                    info["data"].append(content.to_dict())
            info = base_detail(info, paginate)
            return {"code": 200, "data": info}

        except Exception as e:
            current_app.logger.exception(e)
            abort(500, message="参数错误")


class ClassUser(Classes):
    def get(self):
        try:
            all_users_info = (
                userModel.User.query.join(
                    roleModel.Role,
                    roleModel.Role.name == roleModel.PresetRoleChoices.student.value,
                )
                .join(
                    roleModel.UserRole,
                    and_(
                        roleModel.UserRole.user_id == userModel.User.id,
                        roleModel.UserRole.role_id == roleModel.Role.id,
                    ),
                )
                .all()
            )
            return {"code": 200, "data": [u.to_dict() for u in all_users_info]}

        except Exception as e:
            current_app.logger.exception(e)
            abort(500, message="参数错误")

    def post(self):
        args = request.json
        if not all([args["class_id"], args["users"]]):
            abort(400, message="参数错误")

        classes = classesModel.Classes.query.get(int(args["class_id"]))
        if not classes:
            abort(400, message="班级不存在")
        try:
            with db.auto_commit():
                for user_info in args["users"]:
                    user = userModel.User.query.get(user_info["id"])
                    user.class_id = classes.id
                return {"code": 200, "data": "操作成功"}

        except Exception as e:
            current_app.logger.exception(e)
            abort(500, message="参数错误")

    def delete(self):
        args = request.json
        if not all([args["class_id"], args["users"]]):
            abort(400, message="参数错误")

        classes = classesModel.Classes.query.get(int(args["class_id"]))
        if not classes:
            abort(400, message="班级不存在")

        try:
            with db.auto_commit():
                for user_info in args["users"]:
                    user = userModel.User.query.get(user_info["id"])
                    user.class_id = None
                return {"code": 200, "data": "删除成功"}

        except Exception as e:
            current_app.logger.exception(e)
            abort(500, message="参数错误")
